package cn.tedu.weibo.exception;


import cn.tedu.weibo.common.response.JsonResult;
import cn.tedu.weibo.common.response.StatusCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * 全局异常处理器类
 * ControllerAdvice:声明该类为全局异常处理器的类，会捕捉控制器中的异常
 * RestControllerAdvice: 符合注解，等价于Controller+ResponseBody
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    /**
     * 捕获Security框架抛出的用户名或密码错误的异常
     */
    @ExceptionHandler({
            InternalAuthenticationServiceException.class,//用户名错误异常
            BadCredentialsException.class   //密码错误异常
    })
    public JsonResult doHandleAuthenticationException(AuthenticationException e){
        if (e instanceof BadCredentialsException){
            return new JsonResult(StatusCode.PASSWORD_ERROR);
        }
        return new JsonResult(StatusCode.USERNAME_ERROR);
    }


    /*捕获业务异常(业务层抛出的所有异常)*/
    @ExceptionHandler
    public JsonResult doHandleServiceException(ServiceException ex) {
        log.error("RuntimeException is :"+ex.getMessage());
        return new JsonResult(ex.getStatusCode());
    }
    /**
     * ExceptionHandler:该方法为异常处理方法，在该方法内部定义异常处理逻辑；
     * 该方法有一个参数，异常类型，用来接受Controller中抛出的异常逻辑
     */
    @ExceptionHandler
    public JsonResult doHandleRuntimeException(RuntimeException ex) {
        log.error("RuntimeException is :"+ex.getMessage());
        return new JsonResult(StatusCode.OPERATION_FAILED, ex.getMessage());
    }

    @ExceptionHandler
    public JsonResult doHandleIllegalArgumentException(IllegalArgumentException ex) {
        log.error("IllegalArgumentException is :"+ex.getMessage());
        return new JsonResult(StatusCode.OPERATION_FAILED, ex.getMessage());
    }

    /**
     * Throwable:处理所有类型的异常，一般开发最后加
     */
//    @ExceptionHandler
//    public JsonResult doHandleThrowable(Throwable ex){
//        return new JsonResult(8888,"程序运行中出现了Throwable类型的异常");
//    }
    @ExceptionHandler
    public JsonResult doMethodArgumentNotValidException(MethodArgumentNotValidException ex){
        String message= ex.getFieldError().getDefaultMessage();
        return new JsonResult(StatusCode.VALIDATE_ERROR,message);
    }
}
